package com.yellow.car.impl;

import com.yellow.car.api.StationApi;
import com.yellow.car.api.TruckApi;
import com.yellow.car.entity.Station;
import com.yellow.car.entity.Truck;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;

@Service
@Slf4j
public class StationApiImpl implements StationApi {
    private static Station a = null;
    private static Station b = null;
    private static Station c = null;
    private static List<Station> stationList = new ArrayList<>();
    private static HashMap<String, Station> stationMap = new HashMap<>();
    private static ReentrantLock carReentrantLock = new ReentrantLock();
    private static ReentrantLock trunkReentrantLock = new ReentrantLock();

    @Resource
    TruckApi truckApi;

    @Override
    public void init() {
        List<Truck> truckList = truckApi.getTruckList();
        //初始化站点,假设货车初始都停靠在B站点
        a = new Station("A", 30, null);
        b = new Station("B", 40, truckList);
        c = new Station("C", 30, null);
        stationList.add(a);
        stationList.add(b);
        stationList.add(c);
        stationMap.put("A", a);
        stationMap.put("B", b);
        stationMap.put("C", c);
    }

    @Override
    public Station getRandomStation() {
        Random random = new Random();
        int randomIndex = random.nextInt(stationList.size());
        Station station = stationList.get(randomIndex);
        if (station.getCarNum() > 0) {
            return station;
        }
        return null;
    }

    @Override
    public List<Station> getStationInfo() {
        return stationList;
    }

    @Override
    public Boolean reduceByStationName(String stationName, Integer carNum) {
        carReentrantLock.lock();
        try {
            Station station = stationMap.get(stationName);
            if (station != null) {
                Integer haveCarNum = station.getCarNum();
                if (haveCarNum - carNum > 0) {
                    station.setCarNum(haveCarNum-carNum);
                    return true;
                }
            }
        } finally {
            carReentrantLock.unlock();
        }
        return false;
    }

    @Override
    public Boolean addByStationName(String stationName, Integer carNum) {
        if (carNum == 0) {
            return true;
        }
        carReentrantLock.lock();
        try {
            Station station = stationMap.get(stationName);
            if (station != null) {
                Integer haveCarNum = station.getCarNum();
                station.setCarNum(haveCarNum + carNum);
                return true;
            }
        } finally {
            carReentrantLock.unlock();
        }
        return false;
    }

    @Override
    public List<Truck> getFreeTruckList(String stationName) {
        Station station = stationMap.get(stationName);
        if (station != null) {
            return station.getTruckList();
        }
        return null;
    }

    @Override
    public Integer getFreeYellowCarNum(String stationName) {
        Station station = stationMap.get(stationName);
        if (station != null) {
            return station.getCarNum();
        }
        return 0;
    }

    @Override
    public Station getStationInfoByName(String stationName) {
        Station station = stationMap.get(stationName);
        if (station != null) {
            return station;
        }
        return null;
    }

    @Override
    public Boolean reduceTruckByStationName(String stationName, Truck trunk) {
        trunkReentrantLock.lock();
        try {
            Station station = stationMap.get(stationName);
            if (station != null) {
                List<Truck> stationTrunkList = station.getTruckList();
                if (!CollectionUtils.isEmpty(stationTrunkList)) {
                    stationTrunkList.remove(trunk);
                    station.setTruckList(stationTrunkList);
                    return true;
                }
            }
        } finally {
            trunkReentrantLock.unlock();
        }
        return false;
    }

    @Override
    public Boolean addTruckByStationName(String stationName, Truck trunk) {
        trunkReentrantLock.lock();
        try {
            Station station = stationMap.get(stationName);
            if (station != null) {
                List<Truck> stationTrunkList = station.getTruckList();
                if (stationTrunkList == null) {
                    stationTrunkList = new ArrayList<>();
                }
                stationTrunkList.add(trunk);
                station.setTruckList(stationTrunkList);
                return true;
            }
        } finally {
            trunkReentrantLock.unlock();
        }
        return false;
    }

    @Override
    public Station getFreeTruckStation() {
        if (!CollectionUtils.isEmpty(stationList)) {
            return stationList.stream().filter(x -> !CollectionUtils.isEmpty(x.getTruckList())).findFirst().orElse(null);
        }
        return null;
    }

}
